﻿using AutoMapper;
using BaseAPI;
using MemorySiteServer.AuthManage;
using MemorySiteServer.Models;
using MemorySiteServer.ViewModels.Account;
using MemorySiteServer.ViewModels.AccountViewModels;
using MemorySiteServer.VIewModels.Account;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Snowflake.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MemorySiteServer.Controllers
{
    /// <summary>
    /// 用户
    /// </summary>
    [ApiController]
    public class AccountController : BaseController<User>
    {
        private readonly IConfiguration configuration;

        public AccountController(DataContext context, IMapper mapper, IConfiguration _configuration, IdWorker idWorker) : base(context, mapper, idWorker)
        {
            configuration = _configuration;
        }

        /// <summary>
        /// 获取客户端ID、验证码图片
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("api/[controller]/[action]")]
        public ResponseModel<ClientIDResponse> GetClientID()
        {
            UserCode userCode = new UserCode();
            ClientIDResponse loginResponse = new ClientIDResponse()
            {
                ClientID = userCode.ClientID,
                Code = userCode.CreateCode(),
                IsAllowRegister = configuration.GetValue<bool>("AllowedRegister"),
            };
            JwtServer.AddUserCode(userCode);
            return ResponseModel<ClientIDResponse>.Success(loginResponse);
        }

        /// <summary>
        /// 刷新验证码
        /// </summary>
        /// <param name="clientID"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("api/[controller]/[action]")]
        public ResponseModel<string> RefreshCode(string clientID)
        {
            var code = GetNewCode(clientID);
            if (!string.IsNullOrEmpty(code))
                return ResponseModel<string>.Success(code);
            else
                return ResponseModel<string>.Failed();
        }

        /// <summary>
        /// 登录系统
        /// </summary>
        /// <param name="loginRequest"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("api/[controller]/[action]")]
        public async Task<ResponseModel<LoginResponse>> Login(LoginRequest loginRequest)
        {
            //验证ClientID和验证码，验证码错误不强制刷新
            int codeStatus = JwtServer.VerifyUserCode(loginRequest.ClientID, loginRequest.Code);
            bool isCodeRight = false;
            var loginFailResponse = new LoginFailResponse()
            {
                Message = "验证码错误"
            };
            if (codeStatus == 2)
                isCodeRight = true;
            else if (codeStatus == 0)
                loginFailResponse.Message = "ClientID错误";
            if (!isCodeRight)
                return ResponseModel<LoginResponse>.Failed(loginFailResponse.ToJsonString());
            //验证用户名密码，用户名或密码错误验证码强制刷新
            loginFailResponse.Message = "用户名或密码错误";
            loginRequest.doNotUseID = true;
            var responseModel = await Z_GetOne(loginRequest);
            User dbUser;
            if (responseModel.Code == 1)
                dbUser = responseModel.Data;
            else
            {
                loginFailResponse.Code = GetNewCode(loginRequest.ClientID);
                return ResponseModel<LoginResponse>.Failed(loginFailResponse.ToJsonString());
            }
            if (!loginRequest.VerifyLogin(dbUser))
            {
                loginFailResponse.Code = GetNewCode(loginRequest.ClientID);
                return ResponseModel<LoginResponse>.Failed(loginFailResponse.ToJsonString());
            }
            //其他端登录用户下线
            var userAudience = new UserAudience();
            userAudience.Init(dbUser);
            await JwtServer.AddOrUpdateUserAudience(userAudience, context);
            //删除本条验证码
            JwtServer.RemoveUserCode(loginRequest.ClientID, loginRequest.Code);
            //颁发新Token
            var token = JwtServer.GetToken(dbUser.ID.ToString(), userAudience.ServerAudience,
                DateTime.Now.AddSeconds(configuration.GetValue<int>("TokenExpiresTime")));
            LoginResponse loginResponse = new LoginResponse()
            {
                Token = token,
                UserInfo = UserInfo.GetFromUser(dbUser)
            };
            return ResponseModel<LoginResponse>.Success(loginResponse);
        }

        private static string GetNewCode(string clientID)
        {
            var userCodes = JwtServer.GetUserCode(clientID);
            if (userCodes.Count > 0)
            {
                UserCode userCode = userCodes.FirstOrDefault();
                return userCode.CreateCode();
            }
            return null;
        }

        /// <summary>
        /// 注销当前用户
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("api/[controller]/[action]")]
        [Authorize]
        public async Task<ResponseModel<string>> LoginOut()
        {
            //获取用户ID
            var auth = await HttpContext.AuthenticateAsync();
            var claims = auth.Principal.Claims;
            long userID = Convert.ToInt64(claims.FirstOrDefault(x => x.Type == "name").Value);
            //注销用户
            var dbuserAudience = JwtServer.GetUserAudienceFromServer(userID);
            if (dbuserAudience == null)
                return ResponseModel<string>.Failed("无效用户");
            var userAudience = dbuserAudience.Clone();
            userAudience.SetNewServerAudienceValue();
            await JwtServer.AddOrUpdateUserAudience(userAudience, context);
            return ResponseModel<string>.Success(null);
        }

        /// <summary>
        /// 验证Token是否有效
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("api/[controller]/[action]")]
        [Authorize]
        public ResponseModel<UserInfo> VerifyToken()
        {
            var user = JwtServer.GetUser(GetUserID());
            return ResponseModel<UserInfo>.Success(UserInfo.GetFromUser(user));
        }

        /// <summary>
        /// 用户注册
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("api/[controller]/[action]")]
        public async Task<ResponseModel<string>> Register(RegisterRequest registerRequest)
        {
            if (configuration.GetValue<bool>("AllowedRegister") == false)
                return ResponseModel<string>.Failed("系统当前设置为不允许注册");
            //检查用户名重复
            var userExist = await controllerServer.GetOne(user => user.Where(x => x.Name == registerRequest.Name));
            if (userExist.Code == 1 && userExist.Data != null)
                return ResponseModel<string>.Failed("用户名重复");
            return await Z_Create(registerRequest);
        }

        /// <summary>
        /// 获取用户列表
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("api/[controller]/[action]")]
        [Authorize(Policy = "site")]
        //[Authorize(Policy = "site")]
        public async Task<ResponseModel<List<AccountGetListResponse>>> GetList(AccountGetListRequest getListRequest)
        {
            return await Z_GetList(getListRequest);
        }
    }
}
